using System.Windows.Forms;
using NUnit.Framework;
using Nuwanda.TfsSpotlight.Shell.Services.Interfaces;
using Rhino.Mocks;

namespace TfsSpotlight.Tests.Views
{
    [TestFixture]
    public class TabPresenterBaseTests
    {
        private MockRepository _mocks;
        private IWorker _workerMock;
        private IMenuService _menuServiceMock;
        private ILogger _loggerMock;
        private Control _view;

        private TabPresenterBaseTestableStub _testSubject;

        [SetUp]
        public void SetUp()
        {
            this._mocks = new MockRepository();
            this._workerMock = this._mocks.StrictMock<IWorker>();
            this._menuServiceMock = this._mocks.StrictMock<IMenuService>();
            this._loggerMock = this._mocks.StrictMock<ILogger>();
            this._view = new Control();

            this._testSubject = new TabPresenterBaseTestableStub(
                this._view, this._workerMock, this._menuServiceMock, this._loggerMock);
        }

        [Test]
        public void WhenAskedFor_Control_ShouldGet_ViewInstance()
        {
            Assert.AreSame(this._view, this._testSubject.Control);
        }

        [Test]
        public void WhenAskedFor_IsWorking_Should_ReturnWorkingStatusFromWorker()
        {
            var result = true;
            using (this._mocks.Record())
            {
                Expect.Call(this._workerMock.IsWorking).Return(result);
            }

            using (this._mocks.Playback())
            {
                Assert.AreEqual(result, this._testSubject.IsWorking);
            }
        }

        [Test]
        public void WhenAskedTo_HandleActivation_Should_Activate_And_InvalidateCommands()
        {
            using (this._mocks.Record())
            {
                this._menuServiceMock.InvalidateCommands(this._testSubject);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleActivation();
                Assert.IsTrue(this._testSubject.IsActive);
            }
        }

        [Test]
        public void WhenAskedTo_HandleDeactivation_Should_Deactivate_And_DisableCommands()
        {
            using (this._mocks.Record())
            {
                this._menuServiceMock.DisableCommands(this._testSubject);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.HandleDeactivation();
                Assert.IsFalse(this._testSubject.IsActive);
            }
        }

        [Test]
        public void WhenAskedIf_BelongsToServer_Should_ReturnDefaultFalse()
        {
            Assert.IsFalse(this._testSubject.BelongsToServer(null));
        }

        [Test]
        public void WhenAskedTo_WaitTillTheEndOfTheWork_Should_WaitWhenWorkerFinishesHisWork()
        {
            using (this._mocks.Record())
            {
                this._workerMock.WaitTillEnd();
            }

            using (this._mocks.Playback())
            {
                this._testSubject.WaitTillTheEndOfTheWork();
            }
        }

        [Test]
        public void WhanAskedTo_InvalidateCommands_And_IsActive_Should_InvalidateCommands()
        {
            using (this._mocks.Record())
            {
                this._menuServiceMock.InvalidateCommands(this._testSubject);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.Test_IsActive = true;
                this._testSubject.InvalidateHandledCommands();
            }
        }

        [Test]
        public void WhanAskedTo_InvalidateCommands_And_IsNOTActive_Should_NotInvalidateCommands()
        {
            using (this._mocks.Record())
            {
                //no expectations
            }

            using (this._mocks.Playback())
            {
                this._testSubject.Test_IsActive = false;
                this._testSubject.InvalidateHandledCommands();
            }
        }

        [Test]
        public void WhanAskedTo_DisableCommands_And_Should_DisableCommands()
        {
            using (this._mocks.Record())
            {
                this._menuServiceMock.DisableCommands(this._testSubject);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.DisableHandledCommands();
            }
        }

        [Test]
        public void WhenAskedFor_DefaultCommandActivation_And_IsActive_And_IsNOTWorking_Should_ReturnTrue()
        {
            using (this._mocks.Record())
            {
                Expect.Call(this._workerMock.IsWorking).Return(false);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.Test_IsActive = true;
                Assert.IsTrue(this._testSubject.Test_DefaultCommandActivator());
            }
        }

        [Test]
        public void WhenAskedFor_DefaultCommandActivation_And_IsActive_And_IsWorking_Should_ReturnFalse()
        {
            using (this._mocks.Record())
            {
                Expect.Call(this._workerMock.IsWorking).Return(true);
            }

            using (this._mocks.Playback())
            {
                this._testSubject.Test_IsActive = true;
                Assert.IsFalse(this._testSubject.Test_DefaultCommandActivator());
            }
        }

        [Test]
        public void WhenAskedFor_DefaultCommandActivation_And_IsNOTActive_And_IsNOTWorking_Should_ReturnFalse()
        {
            this._mocks.ReplayAll();

            this._testSubject.Test_IsActive = false;
            Assert.IsFalse(this._testSubject.Test_DefaultCommandActivator());

            this._mocks.VerifyAll();
        }

        [Test]
        public void WhenAskedFor_DefaultCommandActivation_And_IsNOTActive_And_IsWorking_Should_ReturnFalse()
        {
            this._mocks.ReplayAll();

            this._testSubject.Test_IsActive = false;
            Assert.IsFalse(this._testSubject.Test_DefaultCommandActivator());

            this._mocks.VerifyAll();
        }
    }
}